iT邦幫忙

2024 iThome 鐵人賽

DAY 16
0
自我挑戰組

30 天 Node.js 探索:基礎、進階與實踐系列 第 16

Day 16:安全性最佳實踐:避免 SQL Injection 和 XSS

  • 分享至 

  • xImage
  •  

接著要學習如何防範常見的 Web 應用程式安全漏洞,包括 SQL 注入 (SQL Injection) 和跨站腳本攻擊 (XSS),以保護 Node.js 應用的安全性。

什麼是 SQL Injection?

SQL 注入 是一種攻擊技術,攻擊者利用應用程式在查詢資料庫時,將惡意的 SQL 語句插入到查詢語句中,從而操控資料庫。這可能導致資料洩露、破壞,甚至讓攻擊者接管整個資料庫。

SQL Injection 的危害

  • 資料竊取: 攻擊者可以讀取應該受保護的資料。
  • 資料破壞: 攻擊者可以刪除、修改資料,或執行任意 SQL 語句。
  • 系統控制: 在某些情況下,攻擊者可以取得系統控制權。

SQL Injection 的範例

假設有一個簡單的登入查詢,將使用者輸入的帳號和密碼直接插入 SQL 語句中:

js
const username = req.body.username;
const password = req.body.password;

const query = `SELECT * FROM users WHERE username = '${username}' AND password = '${password}'`;
db.query(query, (err, result) => {
  if (err) throw err;
  // 登入邏輯
});

攻擊者可以將 username 輸入為 ' OR '1'='1,這樣生成的 SQL 語句會變成:

sql
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = ''

這樣,條件永遠為真,攻擊者可以繞過驗證。

如何防範 SQL Injection?

使用參數化查詢(Prepared Statements)

參數化查詢能有效防止 SQL 注入,因為使用者的輸入不會直接插入 SQL 語句,而是作為參數進行處理。
在使用 Node.js 的 MySQL 庫時,可以改寫查詢語句如下:

js
const query = 'SELECT * FROM users WHERE username = ? AND password = ?';
db.query(query, [username, password], (err, result) => {
  if (err) throw err;
  // 登入邏輯
});

這樣,即便攻擊者輸入惡意的 SQL 語句,資料庫也只會將其當作普通字串處理。

使用 ORM 工具

使用 ORM(Object-Relational Mapping)工具如 Sequelize 或 Mongoose 可以自動處理 SQL 查詢,並內建防範 SQL 注入的機制。

js
npm install sequelize

在 Sequelize 中,查詢使用的參數會自動進行轉義:

js
User.findOne({ where: { username, password } })
  .then(user => {
    if (user) {
      // 登入邏輯
    }
  })
  .catch(err => console.error(err));

避免拼接 SQL 語句

不要將使用者的輸入直接拼接到 SQL 查詢中,這樣能夠有效避免 SQL 注入。

什麼是 XSS (Cross-Site Scripting)?

跨站腳本攻擊(XSS)是一種安全漏洞,攻擊者將惡意腳本注入到網頁中,當其他使用者訪問該頁面時,這些腳本會在受害者的瀏覽器中執行,從而竊取資訊或執行不正當的操作。

XSS 的危害

  • 竊取 Cookie: 攻擊者可以通過惡意腳本竊取使用者的 Session Cookie。
  • 偽造操作: 攻擊者可以模擬使用者的操作,進行未經授權的請求。
  • 網頁劫持: 惡意腳本可以劫持頁面,導致使用者跳轉到釣魚網站或執行惡意代碼。

XSS 的示例

假設有一個留言板應用,使用者可以提交留言,並顯示在網頁上。如果直接將使用者的輸入展示在頁面中而不進行任何處理,攻擊者可能提交以下留言:

html
<script>alert('Your session is stolen!');</script>

當其他使用者查看此頁面時,該惡意腳本會在他們的瀏覽器中執行。

如何防範 XSS?

輸出時進行編碼(HTML Encode)

最基本的 XSS 防護方法是將使用者的輸入進行 HTML 編碼,這樣即便輸入了 HTML 標籤或 JavaScript 代碼,瀏覽器也會將其視為普通文字,而非執行代碼。
在 Express 中,可以使用 ejs 或其他模板引擎自動對變數進行 HTML 編碼:

html
<p><%= userInput %></p>

這樣會將特殊字元如 < 和 > 轉換為 < 和 >,避免它們被解釋為 HTML 或 JavaScript。

使用第三方安全套件

使用 helmet 這樣的安全套件可以增強 Express 應用的安全性。helmet 預設啟用了多種安全策略,能有效減少 XSS 風險。
安裝並使用 helmet:

bash
npm install helmet
js
const helmet = require('helmet');
app.use(helmet());

helmet 會自動設置許多安全 HTTP 頭,阻止 XSS 和其他常見的攻擊。

避免直接插入使用者生成的內容

避免將使用者生成的資料直接插入到 JavaScript、HTML、或屬性中,特別是動態內容,例如內嵌的 JavaScript 代碼。

安全性實踐總結

SQL Injection 防範:

  • 使用參數化查詢或 ORM 工具來避免 SQL 注入。
  • 避免直接拼接 SQL 語句。
    XSS 防範:
  • 將使用者輸入進行 HTML 編碼。
  • 使用安全套件如 helmet 增強應用的防護能力。
  • 避免將使用者資料直接插入到 HTML、JavaScript 或屬性中。

總結

今天學習了如何防範兩種常見的 Web 安全漏洞——SQL Injection 和 XSS。這些漏洞嚴重的威脅了 Web 應用的安全性,了解並實踐相關的防護措施可以幫助建立更安全的應用程式。在後續的應用開發中,這些安全策略將為保護用戶資料和系統穩定性提供保障。


上一篇
Day 15: 錯誤處理與日誌管理
下一篇
Day 17: 使用 WebSocket 實現即時通訊
系列文
30 天 Node.js 探索:基礎、進階與實踐26
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言